package com.eshop.eshopcache.prewarm;

import com.alibaba.fastjson.JSONObject;
import com.eshop.eshopcache.enums.ZkLock;
import com.eshop.eshopcache.model.ProductInfo;
import com.eshop.eshopcache.service.CacheService;
import com.eshop.eshopcache.spring.SpringContext;
import com.eshop.eshopcache.utils.DateUtils;
import com.eshop.eshopcache.zk.ZooKeeperSession;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.Date;
import java.util.Map;

/**
 * @author: Xukai
 * @description: 缓存预热线程
 * @createDate: 2018/8/6 01:55
 * @modified By:
 */
@Slf4j
public class CachePrewarmThread implements Runnable {

    @Override
    public void run() {
        CacheService cacheService = (CacheService) SpringContext.getApplicationContext().getBean("cacheService");
        ZooKeeperSession zooKeeperSession = ZooKeeperSession.getInstance();
        // 获取storm taskid列表
        String taskidList = zooKeeperSession.getNodeData(ZkLock.TASK_ID_LIST.getType(), null);
        if (StringUtils.isNotEmpty(taskidList)) {
            String[] taskIdListSplited = taskidList.split(",");
            for (String taskId : taskIdListSplited) {
                // 尝试快速获得TASK_ID_STATUS_LOCK锁，因为能进行如下业务处理的只能有一个线程
                boolean lock = zooKeeperSession.acquireFastFailedDistributedLock(ZkLock.TASK_ID_STATUS_LOCK.getType(), Long.valueOf(taskId));
                if (lock) {
                    // 获得taskId的处理状态，如果为空表示尚未预热过，有内容表示已经预热，内容为上一次预热成功的时间
                    String taskIdStatus = zooKeeperSession.getNodeData(ZkLock.TASK_ID_STATUS.getType(), Long.valueOf(taskId));
                    if (StringUtils.isEmpty(taskIdStatus)) {
                        // 获得taskId对应的hot product id列表，map格式<count, productId>按count倒序  {3:1234,2:4562,1:78163}
                        String productIdMapJson = zooKeeperSession.getNodeData(ZkLock.TASK_HOT_PRODUCT.getType(), Long.valueOf(taskId));
                        if (StringUtils.isNotEmpty(productIdMapJson)) {
                            Map productIdMap = JSONObject.parseObject(productIdMapJson, Map.class);
                            for (Object o : productIdMap.entrySet()) {
                                Object productId = ((Map.Entry) o).getValue();
                                // 模拟商品查询服务结果
                                String productInfoJSON = "{\"id\": " + productId + ", \"name\": \"iphone7手机\", \"price\": 5599, \"pictureList\":\"a.jpg,b.jpg\", \"specification\": \"iphone7的规格\", \"service\": \"iphone7的售后服务\", \"color\": \"红色,白色,黑色\", \"size\": \"5.5\", \"shopId\": 1, \"modifiedTime\": \"2017-01-01 12:00:00\"}";
                                ProductInfo productInfo = JSONObject.parseObject(productInfoJSON, ProductInfo.class);
                                cacheService.saveProductInfo2LocalCache(productInfo);
                                cacheService.saveProductInfo2RedisCache(productInfo);
                                log.info("【商品缓存预热】商品ID = {}设置到缓存成功", productId);
                            }
                            zooKeeperSession.setNodeDate(ZkLock.TASK_ID_STATUS.getType(), Long.valueOf(taskId), DateUtils.formatTime(new Date()));
                        }
                    }
                    zooKeeperSession.releaseDistributedLock(ZkLock.TASK_ID_STATUS_LOCK.getType(), Long.valueOf(taskId));
                }
            }
        }
    }
}
